Point Update์ Range Query๋ฅผ ์ง์ํ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ SegTree์ด๋ค. ๋ฉ๋ชจ๋ฆฌ๋ 2*N ๋งํผ ์ ์ธํ๋ฉด ๋๋ค.
์์ด์ Index๋ 0๋ถํฐ, ์ ์ฒด Tree์ Index๋ 1๋ถํฐ ์ฌ์ฉ๋๋ ์ํ ์ฝ๋์ด๋ค.
int N;struct SegTree {int d[2'000'010];void build() {for(int i = N - 1; i >= 1; --i) d[i] = d[i<<1] ^ d[i<<1|1];}void updatePoint(int p, int v) {p += N;d[p] = v;for(p>>=1; p > 0; p>>=1) {d[p] = d[p<<1] ^ d[p<<1|1];}}int getRange(int l, int r) {int ret = 0;l += N, r += N;for(;l<=r; l>>=1, r>>=1) {if (l&1) ret ^= d[l++];if (~r&1) ret ^= d[r--];}return ret;}} seg;
์ด ๊ฒฝ์ฐ๋ ๊ฐ๊ธ์ ๋ค๋ฅธ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์. ์ฌ๊ทํธ์ถ ์๋ ๋ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ํด๋ฅผ ๋ณธ๋ค.
Lazy ์ฐ์ฐ์ Range Update ๋๋ฌธ์ ๋ฐ์ํ๋ค. ๋ง์
์ Range Update๋ ๊ฐ๊ธ์ Fenwick
์ผ๋ก ์ฒ๋ฆฌํ์. (Range Update๋ฅผ ๊ตฌ๊ฐ ๋์ 2๊ฐ์ Point Update๋ก ๋์ฒดํ ํ ์ ๋ถ ๊ฐ๋
ํ์ฉํ๋ฉด ๋๋ค)
๋ง์
์ ์ ์ธํ ๊ฒฝ์ฐ์๋ SegTree ์ฌ์ฉ์ด ๊ฐ์ ๋๋๋ฐ, Top-Down์ด Lazy ์ฒ๋ฆฌ์ ์๋์ ์ผ๋ก ํธ๋ฆฌํ๋ค. ์๋ ์์ ๋ Lazy XOR
์ฐ์ฐ์ ์ฒ๋ฆฌํ๋ค.
int N;struct SegNode {int val;int lazy;};struct LazySeg {SegNode tree[2'000'010];int arr[500'010];int init(int x, int s, int e) {if (s == e) return tree[x].val = arr[s];int m = (s+e)>>1;return tree[x].val = init(x<<1,s,m) ^ init(x<<1|1,m+1,e);}void init() {init(1, 1, N);}void push(int x, int s, int e) {if (tree[x].lazy == 0) return;if ((e-s+1) % 2 != 0) tree[x].val ^= tree[x].lazy;if (s != e) {tree[x<<1].lazy ^= tree[x].lazy;tree[x<<1|1].lazy ^= tree[x].lazy;}tree[x].lazy = 0;}void updateRange(int x, int s, int e, int l, int r, int v) {push(x, s, e);if (r < s || e < l) return;if (l <= s && e <= r) {tree[x].lazy ^= v;push(x, s, e);return;}int m = (s+e)>>1;updateRange(x<<1,s,m,l,r,v);updateRange(x<<1|1,m+1,e,l,r,v);tree[x].val = tree[x<<1].val ^ tree[x<<1|1].val;}void updateRange(int l, int r, int v) {updateRange(1, 1, N, l, r, v);}int getRange(int x, int s, int e, int l, int r) {push(x, s, e);if (r < s || e < l) return 0;if (l <= s && e <= r) return tree[x].val;int m = (s+e)>>1;return getRange(x<<1,s,m,l,r) ^ getRange(x<<1|1,m+1,e,l,r);}int getRange(int l, int r) {return getRange(1, 1, N, l, r);}} lazySeg;
์ด๊ธฐ๊ฐ์ด ์ฃผ์ด์ง์ง ์๊ณ ์ฟผ๋ฆฌ๋ก๋ง ์
๋ฐ์ดํธ๊ฐ ๋๋ ๊ฒฝ์ฐ์๋ Dynamicํ๊ฒ ํ์ํ ๊ตฌ๊ฐ๋ง SegTree๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ๋ ์๋ค. ๊ธฐ์กด x<<1
, x<<1|1
์ด ์ข์ฐ ์์์ผ๋ก ๋ด๋ ค๊ฐ๋ ๊ตฌ์กฐ๋ฅผ ๋ํ๋ธ ๊ฒ์ธ๋ฐ, ์ด๋ฅผ ์ง์ง tree ๊ตฌ์กฐ๋ก ๋ฐ๊พผ ๊ฒ.
int N;struct SegNode {int val;int lazy;SegNode* l;SegNode* r;} sn[4'000'000];int sidx = 0;SegNode* newNode() {return &sn[sidx++];}struct LazySeg {SegNode* root;void init() {root = newNode();}void push(SegNode* x, int s, int e) {if (x == 0 || x->lazy == 0) return;if ((e-s+1) % 2 != 0) x->val ^= x->lazy; // ๊ตฌ๊ฐ ํ์์ผ ๋๋ง xor ์๋ฏธ๊ฐ ์๋ค.if (s != e) {if (x->l == 0) x->l = newNode();if (x->r == 0) x->r = newNode();x->l->lazy ^= x->lazy;x->r->lazy ^= x->lazy;}x->lazy = 0;}void updateRange(SegNode* x, int s, int e, int l, int r, int v) {push(x, s, e);if (x == 0) return;if (r < s || e < l) return;if (l <= s && e <= r) {x->lazy ^= v;push(x, s, e);return;}int m = (s+e)>>1;if (x->l == 0) x->l = newNode();if (x->r == 0) x->r = newNode();updateRange(x->l,s,m,l,r,v);updateRange(x->r,m+1,e,l,r,v);x->val = x->l->val ^ x->r->val;}void updateRange(int l, int r, int v) {updateRange(root, 1, N, l, r, v);}int getRange(SegNode* x, int s, int e, int l, int r) {push(x, s, e);if (x == 0) return 0;if (r < s || e < l) return 0;if (l <= s && e <= r) return x->val;int m = (s+e)>>1;return getRange(x->l,s,m,l,r) ^ getRange(x->r,m+1,e,l,r);}int getRange(int l, int r) {return getRange(root, 1, N, l, r);}} lazySeg;